/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_cellvideo.h"

/* Cursor definition */
struct								WMcursor
{
	CELL_OverlayImage				Image;

	uint32_t						Width;
	uint32_t						Height;
	uint32_t						HotX;
	uint32_t						HotY;
	uint32_t*						Pixels;
	uint32_t						Scale;
};

static const uint32_t				ColorMap[4] = {0, 0xFF000000, 0xFFFFFFFF, 0xFF000000};

/* Implementation */
WMcursor*							CELL_CURSOR_Create			(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
{
	WMcursor* cursor = malloc(sizeof(WMcursor));
	if(cursor == NULL)
	{
		SDL_SetError("Failed to allocate cursor");
		return 0;
	}
	memset(cursor, 0, sizeof(WMcursor));

	cursor->Pixels = memalign(128, w * h * sizeof(uint32_t));
	if(!cursor->Pixels)
	{
		SDL_SetError("Failed to allocate memory for cursor image");
		free(cursor);
		return 0;
	}

	/* Convert image */
	for(int i = 0; i != h; i ++)
	{
		for(int j = 0; j != w / 8; j ++)
		{
			Uint8 datat = data[i * (w / 8) + j];
			Uint8 maskt = mask[i * (w / 8) + j];

			for(int k = 0; k != 8; k ++)
			{
				int value = ((datat & (0x80 >> k)) ? 1 : 0) | ((maskt & (0x80 >> k)) ? 2 : 0);
				cursor->Pixels[i * w + (j * 8) + k] = ColorMap[value];
			}
		}
	}

	CELL_IMAGE_Load(&cursor->Image, 0, 0, w, h, cursor->Pixels, w, h);

	cursor->HotX = hot_x;
	cursor->HotY = hot_y;
	cursor->Width = w;
	cursor->Height = h;
	cursor->Scale = 1;

	return cursor;
}

void								CELL_CURSOR_Free			(_THIS, WMcursor *cursor)
{
	if(cursor)
	{
		CELL_IMAGE_Free(&cursor->Image);
		free(cursor->Pixels);
		free(cursor);
	}
}

int									CELL_CURSOR_Show			(_THIS, WMcursor *cursor)
{
	CELL_Video.Cursor.Current = cursor;
	return 1;
}

void 								CELL_CURSOR_Move			(_THIS, int x, int y)
{
	CELL_Video.Cursor.X = x;
	CELL_Video.Cursor.Y = y;
}

uint32_t							CELL_CURSOR_Draw			(WMcursor* aCursor, int32_t aX, int32_t aY, uint32_t aScale)
{
	if(CELL_Video.Cursor.Current || aCursor)
	{
		WMcursor* cursor = aCursor ? aCursor : CELL_Video.Cursor.Current;
		int x = aCursor ? aX : CELL_Video.Cursor.X;
		int y = aCursor ? aY : CELL_Video.Cursor.Y;

		if(cursor->Scale != aScale)
		{
			CELL_IMAGE_Load(&cursor->Image, 0, 0, cursor->Width * aScale, cursor->Height * aScale, cursor->Pixels, cursor->Width, cursor->Height);
			cursor->Scale = aScale;
		}

		/* Draw */
		CELL_IMAGE_Draw_T(&cursor->Image, x - (cursor->HotX * aScale), y - (cursor->HotY * aScale));

		return 1;
	}

	return 0;
}

